#include "Connection.h"

// 创建对象就绑定了
Connection::Connection(EventLoop *loop, Socket *clientsock)
    : loop_(loop), clientsock_(clientsock)
{
    ////////////////////////////////////////////////////////////////////////
    // 为新客户端连接准备读事件，并添加到epoll中。
    clientchannel_ = new Channel(loop_, clientsock_->fd()); // 这里new出来的对象没有释放，这个问题以后再解决。
    // 找到bug了这是是servchannel
    clientchannel_->setreadcallback(std::bind(&Connection::onmessage, this));
    clientchannel_->setcloseCallBack(std::bind(&Connection::closecallback, this));
    clientchannel_->seterrorCallBack(std::bind(&Connection::errorcallback, this));
    clientchannel_->useet(); // 客户端连上来的fd采用边缘触发。
    clientchannel_->enablereading();
    clientchannel_->setwriteCallBack(std::bind(&Connection::writeCallBack, this));
    // 让epoll_wait()监视clientchannel的读事件。
    ////////////////////////////////////////////////////////////////////////
}

Connection::~Connection()
{
    delete clientchannel_;
    delete clientsock_;
}

int Connection::fd() const
{
    return clientsock_->fd();
}
std::string Connection::getiP() const
{
    return clientsock_->getiP();
}
uint16_t Connection::getport() const
{
    return clientsock_->getport();
}

void Connection::closecallback() // TCP断开连接的回调函数 ，提供channel 回调
{
    // printf("client(eventfd=%d) disconnected.\n", fd());
    // close(fd()); // 关闭客户端的fd。
    closeCallBack_(this);
}
void Connection::errorcallback() // TcP连接错误的回调函数，提供Channel 回调
{
    // printf("client(eventfd=%d) error.\n", fd());
    // close(fd()); // 关闭客户端的fd。
    errorCallBack_(this);
}
void Connection::setCloseCallBack(func_t func) // TCP断开连接的回调函数 ，提供channel 回调
{
    closeCallBack_ = func;
}
void Connection::setErrorCallBack(func_t func) // TcP连接错误的回调函数，提供Channel 回调
{
    errorCallBack_ = func;
}

void Connection::onmessage()
{
    printf("%d", 111);
    char buffer[1024];
    while (true) // 由于使用非阻塞IO，一次读取buffer大小数据，直到全部的数据读取完毕。
    {
        bzero(&buffer, sizeof(buffer));
        ssize_t nread = read(fd(), buffer, sizeof(buffer));
        if (nread > 0) // 成功的读取到了数据。
        {
            // 把接收到的报文内容原封不动的发回去。
            // printf("recv(eventfd=%d):%s\n", fd(), buffer);
            // send(fd(), buffer, strlen(buffer), 0);

            inputbuffer_.append(buffer, nread);
        }
        else if (nread == -1 && errno == EINTR) // 读取数据的时候被信号中断，继续读取。
        {
            continue;
        }
        else if (nread == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) // 全部的数据已读取完毕。
        {

            // printf("recv(eventfd=%d):%s\n", fd(), inputbuffer_.data());
            while (true)
            {
                int len;
                memcpy(&len, inputbuffer_.data(), 4);
                if (inputbuffer_.size() < len + 4)
                {
                    break;
                }
                // 从buffer中获取一个报文
                std::string message(inputbuffer_.data() + 4, len);
                inputbuffer_.erase(0,len + 4);
                printf("message(eventfd=%d):%s\n", fd(), message.c_str());

                messagecallback_(this, message);
            }

            break;
        }
        else if (nread == 0) // 客户端连接已断开。
        {
            // printf("client(eventfd=%d) disconnected.\n", fd_);
            // close(fd_); // 关闭客户端的fd。
            closeCallBack_(this);
            break;
        }
    }
}

void Connection::setonmessagecb(func_t2 fn)
{
    messagecallback_ = fn;
}

void Connection::send(const char* data, size_t size)
{
    outputbuffer_.appendwithhead(data, size);
    // 注册写事件
    clientchannel_->enablewriteing();

}

void Connection::writeCallBack()
{
    int writen = ::send(fd(), outputbuffer_.data(), outputbuffer_.size(), 0); // 尝试把发送缓冲区的的数据全部发送出去
    if(outputbuffer_.size()==0)
    {
        clientchannel_->disablereading();
        sendcompletecallback_(this);
    }
}

void Connection::setsendcompletecallback(func_t func) // TcP连接错误的回调函数，提供Channel 回调
{
    sendcompletecallback_ = func;
}
